package com.scoe.gcs.comms;

import org.appcelerator.kroll.KrollModule;
import org.appcelerator.kroll.annotations.Kroll;

import org.appcelerator.titanium.TiApplication;
import org.appcelerator.titanium.TiBlob;
import org.appcelerator.titanium.util.TiRHelper;
import org.appcelerator.titanium.util.TiRHelper.ResourceNotFoundException;
import org.appcelerator.kroll.common.Log;
import org.appcelerator.kroll.common.TiConfig;

import com.MAVLink.MAVLink;
import com.MAVLink.Messages.IMAVLinkMessage;
import com.MAVLink.Messages.common.msg_heartbeat;
import com.scoe.gcs.comms.CommonSettings;
import com.scoe.gcs.comms.CommunicationClient;
import com.scoe.gcs.comms.activites.GPSActivity;
import com.scoe.gcs.comms.activites.HUDActivity;
import com.scoe.gcs.comms.activites.StatusActivity;
import com.scoe.gcs.comms.demo.HUDActivityDemo;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;

import java.lang.String;


@Kroll.module(name="ScoeGcsComms", id="com.scoe.gcs.comms")
public class ScoeGcsCommsModule extends KrollModule
{

	// Standard Debugging variables
	private static final String LCAT = "ScoeGcsCommsModule";
	private static final boolean DBG = TiConfig.LOGD;
	TiApplication appContext = TiApplication.getInstance();
	private Activity rootActivity = appContext.getCurrentActivity();
	private String status = "";
	public CommsProxy commsProxy = new CommsProxy();
	
	//object variables
	HUDActivity hudActivity = null;
	GPSActivity gpsActivity = null;
	StatusActivity statusActivity = null;

	// You can define constants with @Kroll.constant, for example:
	// @Kroll.constant public static final String EXTERNAL_NAME = value;
	
	public ScoeGcsCommsModule()
	{
		super();
		TiApplication.getInstance().addAppEventProxy(this);
		TiApplication.getInstance().addAppEventProxy(commsProxy);
		
	}

	@Kroll.onAppCreate
	public static void onAppCreate(TiApplication app)
	{
		Log.d(LCAT, "inside onAppCreate");
		// put module init code that needs to run when the application is created
		
	}

	@Override
	public void onStart(Activity activity)
	{
		// This method is called when the module is loaded and the root context is started
		Log.d(LCAT, "[MODULE LIFECYCLE EVENT] start");
		super.onStart(activity);
		
		SharedPreferences settings = rootActivity.getSharedPreferences(CommunicationClient.PREFS_NAME, 0);
		if(settings.contains(CommunicationClient.DEFAULT_ORIENTATION)){
			String address = settings.getString(CommunicationClient.DEFAULT_ORIENTATION, "");
			
			int orient = CommonSettings.ORIENTATION_DEFAULT;
			
			if(	address.equals(CommonSettings.LANDSCAPE))
				orient = CommonSettings.ORIENTATION_LANDSCAPE;
			else if(	address.equals(CommonSettings.PORTRAIT))
				orient = CommonSettings.ORIENTATION_PORTRAIT;

			if( orient != CommonSettings.ORIENTATION_DEFAULT){
				if( CommonSettings.setOrientation(rootActivity, orient))
					return;
			}
				
		}
		//ba.init();
	}
	
	@Override
	public void onStop(Activity activity)
	{
		// This method is called when the root context is stopped
		Log.d(LCAT, "[MODULE LIFECYCLE EVENT] stop");
		//super.onStop(activity);
	}
	
	@Override
	public void onDestroy(Activity activity)
	{
		// This method is called when the root context is being destroyed

		Log.d(LCAT, "[MODULE LIFECYCLE EVENT] destroy");
		super.onDestroy(activity);
		ba.onDestroy();
	}


	// Methods
	
	private static String byte2int(byte [] buffer){  
        String h = "";  
          
        for(int i = 0; i < buffer.length; i++){  
        	int temp = (buffer[i] & 0xFF);

            h = h + " "+ temp;  
        }  
          
        return h;  
          
    }  
	
	public void onActivityResult(int requestCode, int resultCode, Intent data) {
		ba.onActivityResult(requestCode, resultCode, data);

	}
	
	private void selectProtocol() {
		final CharSequence[] items = {"AC1", "MAVLink"};

		AlertDialog.Builder builder = new AlertDialog.Builder(rootActivity);
		builder.setTitle("Pick a Protocol");
		builder.setItems(items, new DialogInterface.OnClickListener() {
		    public void onClick(DialogInterface dialog, int item) {
		    	
				// Save the modem for next time
				SharedPreferences settings = rootActivity.getSharedPreferences(CommunicationClient.PREFS_NAME, 0);
				SharedPreferences.Editor editor = settings.edit();
				if(item == 0){
					editor.putString(CommunicationClient.ACTIVE_PROTOCOL, CommonSettings.AC1);
					CommonSettings.currentProtocol = CommonSettings.AC1_PROTOCOL;
					
				}else{
					editor.putString(CommunicationClient.ACTIVE_PROTOCOL, CommonSettings.MAVLink);
					CommonSettings.currentProtocol = CommonSettings.MAVLINK_PROTOCOL;
					
				}
				
			    editor.commit();
			    status = "Protocol Selected";
			}
		});
		
		AlertDialog alert = builder.create();
		
		alert.show();
	}
	
	CommunicationClient ba = new CommunicationClient(rootActivity) {
		
		@Override
		public void notifyConnected() {
			
			if( CommonSettings.isNone())
				selectProtocol();
			
			if( CommonSettings.isProtocolAC1()){
				status = "Connected";
				
			}
			else if( CommonSettings.isProtocolMAVLink()){
				//Log.d(LCAT, "Protocol set to MAVLink");;
				msg_heartbeat msg = new msg_heartbeat();
				msg.type = MAVLink.MAV_TYPE.MAV_TYPE_GCS;
				msg.autopilot = MAVLink.MAV_AUTOPILOT.MAV_AUTOPILOT_GENERIC;
				sendBytesToComm(MAVLink.createMessage(msg));
			
			}else{
				status = "Protocol Selection";
				
			}

		}

		@Override
		public void notifyDeviceNotAvailable() {
			status = "Device not available";
			
		}

		@Override
		public void notifyDisconnected() {
			if( CommonSettings.isNone())
				status = "!!No Protocol!!";
			
			if( CommonSettings.isProtocolAC1()){
				status = "!!AC1 Disconnected!!";
				commsProxy.notifyTitaniumHeartbeat(false);
			}

			else if( CommonSettings.isProtocolMAVLink()){
				status = "MAVLink Disconnected";
				commsProxy.notifyTitaniumHeartbeat(false);
			}
			
		}

		@Override
		public void notifyReceivedData(int count,  IMAVLinkMessage m) {
	
			if( m.messageType == msg_heartbeat.MAVLINK_MSG_ID_HEARTBEAT){
				MAVLink.CURRENT_SYSID = m.sysID;
				MAVLink.ARDUCOPTER_COMPONENT_ID = m.componentID;
				status = "Heartbeat";
				commsProxy.notifyTitaniumHeartbeat(true);
			}
		}
	};
	

	private int getIdOfModuleAsset(String assetName, String typeWithDot)
	{
		// Use this to locate resources in the R.java file (e.g. platform/android/res/drawable)
		// In case the caller passes in the asset name with the extension, strip it off
		// Prefix the asset name with type

		int dot = assetName.lastIndexOf(".");
		String resourceName = typeWithDot + ((dot > 0) ? assetName.substring(0, dot) : assetName);

		int result = 0;
		try {
			result = TiRHelper.getApplicationResource(resourceName);
		} catch (ResourceNotFoundException e) {
			Log.d(LCAT, "[ASSETSDEMO] EXCEPTION -- RESOURCE NOT FOUND");
		}

		return result;
	}
	
	// Methods exposed to JS
	
	//hud properties
	
	@Kroll.method 
	public void startHUD() {
		Log.d(LCAT, "Starting HUD Communications");
		hudActivity = new HUDActivity(rootActivity);
	}
	
	@Kroll.method
	public void stopHUD() {
		Log.d(LCAT, "Stopping HUD Communications");
		hudActivity = null;
	}
	
	//gps properties
	
	@Kroll.method 
	public void startGPS() {
		Log.d(LCAT, "Starting GPS Communications");
		gpsActivity = new GPSActivity(rootActivity);
	}
	
	@Kroll.method
	public void stopGPS() {
		Log.d(LCAT, "Stopping GPS Communications");
		gpsActivity = null;
	}
	
	//status properties
	
	@Kroll.method 
	public void startStatus() {
		Log.d(LCAT, "Starting Status Communications");
		statusActivity = new StatusActivity(rootActivity);
	}
	
	@Kroll.method
	public void stopStatus() {
		Log.d(LCAT, "Stopping Status Communications");
		statusActivity = null;
	}
	
	@Kroll.setProperty @Kroll.method
	public void setRadioAddress(String address) {
		SharedPreferences settings = rootActivity.getSharedPreferences(CommunicationClient.PREFS_NAME, 0);
		SharedPreferences.Editor editor = settings.edit();
		editor.putString(CommunicationClient.DEFAULT_MODEM, address);
		editor.commit();
	}
	
	@Kroll.setProperty @Kroll.method
	public void setHUDheight(int height) {
		hudActivity.hudHeight = height;
	}
	
	@Kroll.setProperty @Kroll.method
	public void setHUDwidth(int width) {
		hudActivity.hudWidth = width;
	}
	
	@Kroll.getProperty @Kroll.method
	public TiBlob getHUDimage() {
		return hudActivity.blob;
	}
	
	@Kroll.method
	public void startDemo(){
		rootActivity.startActivity(new Intent(rootActivity, HUDActivityDemo.class));
	}
	
	@Kroll.method
	public void bainit(){
		ba.init();
	}
	
	// Properties
	@Kroll.getProperty @Kroll.method
	public String getExampleProp()
	{
		Log.d(LCAT, "get example property");
		return "hello world";
	}
	
	
	@Kroll.setProperty @Kroll.method
	public void setExampleProp(String value) {
		Log.d(LCAT, "set example property: " + value);
	}

}

